﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Diagnostics;
using MachineQA;
using MachineQA.Properties;
using System.Data.Objects.DataClasses;

namespace MachineQA.Model
{
    /// <summary>
    /// Partially defined by EF model. Adding error checking.
    /// </summary>
    public partial class Machine : IDataErrorInfo
    {
        public static Machine CreateMachine(string name, Location location,
            List<Energy> energies)
        {
            Machine retVal = new Machine();
            retVal.Name = name;
            retVal.Location = location;
            EntityCollection<Energy> temp = new EntityCollection<Energy>();
            energies.ForEach((i) => temp.Add(i));
            retVal.Energies = temp;
            return retVal;
        }

        #region IDataErrorInfo Implementation
        public string Error
        {
            get { return null; }
        }

        public string this[string propertyName]
        {
            get { return this.GetValidationError(propertyName); }
        }
        #endregion // IDataErrorInfo Implementation

        #region Validation

        static readonly string[] ValidatedProperties =
        {
            "Name",
            "Energies"
        };

        string GetValidationError(string propertyName)
        {
            if (Array.IndexOf(ValidatedProperties, propertyName) < 0)
                return null;

            string error = null;

            switch (propertyName)
            {
                case "Name":
                    error = this.ValidateName();
                    break;
                case "Energies":
                    error = this.ValidateEnergies();
                    break;
                default:
                    Debug.Fail(Resources.UnexpectedPropertyError + propertyName);
                    break;
            }
            return error;
        }

        public bool IsValid
        {
            get
            {
                foreach (string property in ValidatedProperties)
                    if (GetValidationError(property) != null)
                        return false;

                return true;
            }
        }

        private string ValidateEnergies()
        {
            foreach (Energy curEnergy in this.Energies)
            {
                // An energy can only be added to a machine once.
                if (this.Energies.Where((i) => i.Modality_Id == curEnergy.Modality_Id
                    && i.value == curEnergy.value).Count() > 1)
                    return Resources.DuplicateMachineEnergyValidationError;

                // An energy cannot be added to a machine that hasn't been saved to the
                // entity model's Energies collection already.
                if (!Constants.entities.Energies.Contains(curEnergy))
                    return Resources.EnergyDoesntExistError;
            }
            return null;
        }

        private string ValidateName()
        {
            if (Constants.entities.Machines.Where((i) => i.Id != this.Id && i.Name == this.Name).Count() > 0)
            {
                return Resources.DuplicateMachineValidationError;
            }
            return null;
        }
        #endregion // Validation
    }
}
